home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 February: Tool Chest / Dev.CD Feb 99 TC.toast / Tool Chest / Interapplication Communication / ScriptableStuffItEngine / Project / SSE_FindFiles.cp < prev    next >
Encoding:
Text File  |  1998-12-02  |  6.6 KB  |  286 lines  |  [TEXT/CWIE]

  1. /*
  2.     You may incorporate this Apple sample source code into your program(s) without
  3.     restriction. This Apple sample source code has been provided "AS IS" and the
  4.     responsibility for its operation is yours. You are not permitted to redistribute
  5.     this Apple sample source code as "Apple sample source code" after having made
  6.     changes. If you're going to re-distribute the source, we require that you make
  7.     it clear in the source that the code was descended from Apple sample source
  8.     code, but that you've made changes.
  9. */
  10.  
  11. #include "ScriptableStuffItEngine.h"    // app
  12. #include "Search.h"                        // MoreFiles
  13. #include "MoreFilesExtras.h"            // MoreFiles
  14.  
  15. #include <AppleEvents.h>
  16. #include <Files.h>
  17. #include <Errors.h>
  18. #include <PLStringFuncs.h>
  19. #include <TextUtils.h>
  20.  
  21. enum
  22. {
  23.     eDontCareAboutName    = 0x0000,
  24.     eNameBeginsWith        = 0x0001,
  25.     eNameIs                = 0x0002,
  26.     eNameContains        = 0x0004,
  27.     eNameEndsWith        = 0x0008
  28. };
  29.  
  30. typedef struct
  31. {
  32.     UInt16                    caresAboutName;
  33.     OSType                    fdType;
  34.     FSSpec                    toSearch;
  35.     CSParam                    csParam;
  36.     CInfoPBRec                searchInfo1;
  37.     CInfoPBRec                searchInfo2;
  38.     Str31                    nameBuffer;
  39.     FSSpec                    matches [ ];
  40. }
  41. tFindFilesDataBlock, *tFindFilesDataBlockP;
  42.  
  43. static pascal OSErr MyMemError (void)
  44. {
  45.     OSErr err = MemError ( );
  46. //    if (err == -113) Debugger ( );
  47.     return err;
  48. }
  49.  
  50. static pascal OSErr FinishFindFilesSetUp (const AppleEvent *event, tFindFilesDataBlock &ffdb)
  51. {
  52.     OSErr err = noErr;
  53.  
  54.     UInt8 *param = nil;
  55.  
  56.     ffdb.caresAboutName = eDontCareAboutName;
  57.  
  58.     if (!(err = GetOptionalTextParameter (event,keyNameBeginsWith,¶m)))
  59.     {
  60.         ffdb.caresAboutName |= eNameBeginsWith;
  61.     }
  62.  
  63.     if (!err && param)
  64.     {
  65.         Size size = GetPtrSize (Ptr (param));
  66.  
  67.         if (!(err = MyMemError ( )))
  68.         {
  69.             if (size > 31)
  70.                 err = paramErr;
  71.             else
  72.             {
  73.                 ffdb.csParam.ioSearchBits |= fsSBPartialName;
  74.                 BlockMoveData (param, 1 + ffdb.nameBuffer, size);
  75.                 ffdb.nameBuffer [0] = size;
  76.                 ffdb.csParam.ioSearchInfo1->hFileInfo.ioNamePtr = ffdb.nameBuffer;
  77.             }
  78.         }
  79.  
  80.         DisposePtr (Ptr (param));
  81.         if (!err) err = MyMemError ( );
  82.         param = nil;
  83.     }
  84.  
  85.     if (!err && !(err = GetOptionalTextParameter (event,keyFileTypeIs,¶m)))
  86.     {
  87.         if (param)
  88.         {
  89.             Size size = GetPtrSize (Ptr (param));
  90.  
  91.             if (!(err = MyMemError ( )))
  92.             {
  93.                 if (size != sizeof (ffdb.fdType))
  94.                     err = paramErr;
  95.                 else
  96.                 {
  97.                     ffdb.searchInfo2.hFileInfo.ioFlAttrib |= ioDirMask;            // we care whether it is a dir
  98.  
  99.                     BlockMoveData (param, &(ffdb.fdType), size);
  100.  
  101.                     if ('fold' == ffdb.fdType || 'ƒldr' == ffdb.fdType)            // magic file types for directories
  102.                         ffdb.searchInfo1.hFileInfo.ioFlAttrib |= ioDirMask;        // it must be a dir
  103.                     else
  104.                     {
  105.                         ffdb.csParam.ioSearchBits |= fsSBFlFndrInfo;
  106.                         ffdb.csParam.ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = ffdb.fdType;
  107.                         ffdb.csParam.ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
  108.                     }
  109.                 }
  110.             }
  111.         }
  112.  
  113.         DisposePtr (Ptr (param));
  114.         if (!err) err = MyMemError ( );
  115.         param = nil;
  116.     }
  117.  
  118.     return err;
  119. }
  120.  
  121. static pascal OSErr AddHitsToReply (AEDescList *replyList, tFindFilesDataBlock &ffdb)
  122. {
  123.     OSErr err = noErr;
  124.  
  125.     if (long index = ffdb.csParam.ioActMatchCount)
  126.     {
  127.         FSSpecPtr scan = ffdb.matches + index - 1;
  128.  
  129.         do
  130.         {
  131.             Boolean addThisItem = true;
  132.  
  133.             if (eNameBeginsWith & ffdb.caresAboutName)
  134.             {
  135.                 if (scan->name [0] < *(ffdb.nameBuffer))
  136.                     addThisItem = false;
  137.                 else if (scan->name [0] > 31)
  138.                 {
  139.                     err = paramErr;
  140.                     break;
  141.                 }
  142.                 else
  143.                 {
  144.                     Str31 victim;
  145.                     PLstrcpy (victim,scan->name);
  146.                     victim [0] = *(ffdb.nameBuffer);
  147.                     if (!EqualString (victim, ffdb.nameBuffer, false, true))
  148.                         addThisItem = false;
  149.                 }
  150.             }
  151.  
  152.             if (addThisItem)
  153.             {
  154.                 Size dataSize = sizeof (*scan) - sizeof (scan->name) + *(scan->name) + 1;
  155.                 err = AEPutPtr (replyList, 0, typeFSS, scan, dataSize);
  156.                 if (err) break;
  157.             }
  158.         }
  159.         while (--scan, --index);
  160.     }
  161.  
  162.     return err;
  163. }
  164.  
  165. pascal OSErr FindFiles (const AppleEvent *event, AppleEvent *reply)
  166. {
  167.     OSErr err = noErr;
  168.  
  169.     if (reply->dataHandle)
  170.     {
  171.         PurgeMem (maxSize);
  172.         err = MyMemError ( );
  173.  
  174.         if (!err || err == memFullErr)
  175.         {
  176.             //
  177.             //    Allocate 2/5 of available memory, leaving a 48K cushion.
  178.             //
  179.  
  180.             Size blockSize = CompactMem (maxSize);
  181.             err = MyMemError ( );
  182.  
  183.             if (!err)
  184.             {
  185.                 blockSize -= 1024L * 48L;
  186.                 blockSize *= 2;
  187.                 blockSize /= 5;
  188.  
  189.                 long ioReqMatchCount = (blockSize - sizeof (tFindFilesDataBlock)) / sizeof (FSSpec);
  190.  
  191.                 if (ioReqMatchCount < 1)
  192.                     err = memFullErr;
  193.                 else
  194.                 {
  195.                     if (ioReqMatchCount > 10)
  196.                         ioReqMatchCount = 10;
  197.  
  198.                     blockSize = (ioReqMatchCount * sizeof (FSSpec)) + sizeof (tFindFilesDataBlock);
  199.  
  200.                     tFindFilesDataBlockP blockP = tFindFilesDataBlockP (::NewPtrClear (blockSize));
  201.  
  202.                     if (!blockP)
  203.                         err = MyMemError ( );
  204.                     else
  205.                     {
  206.                         DescType    actualType;
  207.                         Size        actualSize = sizeof (blockP->toSearch);
  208.  
  209.                         if (!(err = ::AEGetParamPtr (event,keySearchTarget,typeFSS,&actualType,&(blockP->toSearch),actualSize,&actualSize)))
  210.                         {
  211.                             blockP->csParam.ioVRefNum                    = blockP->toSearch.vRefNum;
  212.                             blockP->csParam.ioMatchPtr                    = blockP->matches;
  213.                             blockP->csParam.ioReqMatchCount                = ioReqMatchCount;
  214.                             blockP->csParam.ioSearchInfo1                = &(blockP->searchInfo1);
  215.                             blockP->csParam.ioSearchInfo2                = &(blockP->searchInfo2);
  216.                             blockP->csParam.ioSearchBits                = fsSBFlAttrib;
  217.  
  218.                             long        dirID;
  219.                             Boolean        isDir;
  220.  
  221.                             if (blockP->toSearch.parID != fsRtParID)
  222.                                 err = ::FSpGetDirectoryID (&(blockP->toSearch), &dirID, &isDir);
  223.                             else
  224.                             {
  225.                                 dirID    = fsRtDirID;
  226.                                 isDir    = true;
  227.                             }
  228.  
  229.                             if (!err)
  230.                             {
  231.                                 if (!isDir)
  232.                                     err = afpObjectTypeErr;
  233.                                 else if (!(err = ::FinishFindFilesSetUp (event, *blockP)))
  234.                                 {
  235.                                     OSErr err2 = noErr;
  236.  
  237.                                     AEDescList descList;
  238.  
  239.                                     if (!(err = ::AECreateList (nil, 0, false, &descList)))
  240.                                     {
  241.                                         Boolean done = false;
  242.  
  243.                                         do
  244.                                         {
  245.                                             if (dirID == fsRtDirID)
  246.                                                 err = ::PBCatSearchSync (&(blockP->csParam));
  247.                                             else
  248.                                                 err = ::IndexedSearch (&(blockP->csParam), dirID);
  249.  
  250.                                             if (err == eofErr)
  251.                                             {
  252.                                                 done = true;
  253.                                                 err = noErr;
  254.                                             }
  255.  
  256.                                             if (!err && blockP->csParam.ioActMatchCount)
  257.                                             {
  258.                                                 err = ::AddHitsToReply (&descList,*blockP);
  259.                                                 EventRecord dummyEvent;
  260.                                                 (void) WaitNextEvent (0,&dummyEvent,10,nil);
  261.                                             }
  262.                                         }
  263.                                         while (!done);
  264.  
  265.                                         if (!err)
  266.                                         {
  267.                                             err = ::AEPutParamDesc (reply,keyDirectObject,&descList);
  268.                                         }
  269.  
  270.                                         err2 = ::AEDisposeDesc (&descList);
  271.                                         if (!err) err = err2;
  272.                                     }
  273.                                 }
  274.                             }
  275.                         }
  276.                         ::DisposePtr (Ptr (blockP));
  277.                         if (!err) err = MyMemError ( );
  278.                     }
  279.                 }
  280.             }
  281.         }
  282.     }
  283.  
  284.     return err;
  285. }
  286.